//
// Created by postgres on 7/30/17.
//
#include "../include/09sort/merge_sort.h"
#include "../include/09sort/files.h"

void adjust(Datatype node[], Datatype leaves[], int n) {
    int i;
    Datatype temp;
    for (i = (n + k) / 2; i > 0; i = i / 2) {
        if (leaves[n] > leaves[node[i]]) {
            temp = node[i];
            node[i] = n;
            n = temp;
            if (i == 1)node[0] = n;
        }
    }
    if (node[0] == k || leaves[n] < leaves[node[0]])
        node[0] = n;
}

void create_loser_tree(Datatype node[], Datatype leaves[]) {
    leaves[k] = MinValue;
    int i;
    for (i = 0; i < k; i++) {//设置ls败者的初值都为k， k位置的关键字已经设置为了-1，
        node[i] = k;
    }
    for (i = k - 1; i >= 0; i--) {//一次从存储点第一个关键词开始进行调整
        Adjust(node, leaves, i);
    }
    //leaves[3]=13;
    //Adjust(node,leaves,3);
}

FILE *next_fp(FILE *fp_r[]) {
    int j;
    for (j = 0; j < k; j++) {
        if (feof(fp_r[j]) != 1) {
            return fp_r[j];
        }
    }
    return NULL;
}

void file_close(FILE *fp_r[]) {
    int j;
    for (j = 0; j < k; j++) {
        fclose(fp_r[j]);
    }
}

void loser_tree_main(int fileNums) {
    int file_nums = fileNums;
    //printf("%d",INT_MAX);
    Datatype node[k];
    char dest[arrlen];
    Datatype leaves[k + 1];//存放带归并段的关键字，;
    int i, j, fileid_in, fileid_out=0, len,directory_times = 1;
    FILE *fp_r[k], *fp_in = NULL, *fp_w;
    while (fileid_out!=1) {
        fileid_in = 0, fileid_out = 0, len = 0;
        directory_times++;
        while (fileid_in < file_nums) {
            printf("--------------file_out:%d----------\n", fileid_out);
            get_filename(dest, arrlen, directory_times, fileid_out++);
            fp_w = fopen(dest, "w");
            for (i = 0; i < k; i++) {
                if(file_nums<k&&i!=0&&i%file_nums==0){
                    fileid_in=0;
                }
                get_filename(dest, arrlen, directory_times-1, fileid_in);
                if(file_nums<k&&i>file_nums-1){
                    fp_r[i]=fp_r[fileid_in];
                }else{
                    fp_r[i] = fopen(dest, "r+");
                }
                len = fscanf(fp_r[i], "id:%d ", &leaves[i]);
                fileid_in++;
            }
            create_loser_tree(node, leaves);
            while (leaves[node[0]] != MaxValue) {
                i = node[0];
                fprintf(fp_w, "id:%d\n", leaves[i]);
                printf("%d:%d\n", i, leaves[i]);
                if (feof(fp_r[i]) != 1) fp_in = fp_r[i];
                else fp_in = next_fp(fp_r);
                if (fp_in != NULL) {
                    len = fscanf(fp_in, "id:%d ", &leaves[i]);
                } else {
                    leaves[i] = MaxValue;
                }
                adjust(node, leaves, i);
            }
            fclose(fp_w);
            file_close(fp_r);
        }
        file_nums = fileid_out;
    }
}
